﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Utils.S7Help
{
    public static class ByteArrayLib
    {
        //
        // 摘要:
        //     根据起始地址和长度自定义截取字节数组
        //
        // 参数:
        //   data:
        //     字节数组
        //
        //   start:
        //     开始字节
        //
        //   length:
        //     截取长度
        //
        // 返回结果:
        //     字节数组
        [Description("根据起始地址和长度自定义截取字节数组")]
        public static byte[] GetByteArrayFromByteArray(byte[] data, int start, int length)
        {
            if (start < 0)
            {
                throw new ArgumentException("开始索引不能为负数");
            }

            if (length <= 0)
            {
                throw new ArgumentException("长度必须为正数");
            }

            if (data.Length < start + length)
            {
                throw new ArgumentException("字节数组长度不够或开始索引太大");
            }

            byte[] array = new byte[length];
            Array.Copy(data, start, array, 0, length);
            return array;
        }

        //
        // 摘要:
        //     根据起始地址自定义截取字节数组
        //
        // 参数:
        //   data:
        //     字节数组
        //
        //   start:
        //     开始字节
        //
        // 返回结果:
        //     字节数组
        [Description("根据起始地址自定义截取字节数组")]
        public static byte[] GetByteArrayFromByteArray(byte[] data, int start)
        {
            return GetByteArrayFromByteArray(data, start, data.Length - start);
        }

        //
        // 摘要:
        //     从字节数组中截取2个字节,并按指定字节序返回
        //
        // 参数:
        //   value:
        //     字节数组
        //
        //   start:
        //     开始索引
        //
        //   dataFormat:
        //     字节顺序，默认为ABCD
        //
        // 返回结果:
        //     字节数组
        [Description("从字节数组中截取2个字节,并按指定字节序返回")]
        public static byte[] Get2BytesFromByteArray(byte[] value, int start, DataFormat dataFormat = DataFormat.ABCD)
        {
            byte[] byteArrayFromByteArray = GetByteArrayFromByteArray(value, start, 2);
            switch (dataFormat)
            {
                case DataFormat.ABCD:
                case DataFormat.CDAB:
                    return byteArrayFromByteArray.Reverse().ToArray();
                case DataFormat.BADC:
                case DataFormat.DCBA:
                    return byteArrayFromByteArray;
                default:
                    return byteArrayFromByteArray;
            }
        }

        //
        // 摘要:
        //     从字节数组中截取4个字节,并按指定字节序返回
        //
        // 参数:
        //   value:
        //     字节数组
        //
        //   start:
        //     开始索引
        //
        //   dataFormat:
        //     字节顺序，默认为ABCD
        //
        // 返回结果:
        //     字节数组
        [Description("从字节数组中截取4个字节,并按指定字节序返回")]
        public static byte[] Get4BytesFromByteArray(byte[] value, int start, DataFormat dataFormat = DataFormat.ABCD)
        {
            byte[] byteArrayFromByteArray = GetByteArrayFromByteArray(value, start, 4);
            byte[] array = new byte[4];
            switch (dataFormat)
            {
                case DataFormat.ABCD:
                    array[0] = byteArrayFromByteArray[3];
                    array[1] = byteArrayFromByteArray[2];
                    array[2] = byteArrayFromByteArray[1];
                    array[3] = byteArrayFromByteArray[0];
                    break;
                case DataFormat.CDAB:
                    array[0] = byteArrayFromByteArray[1];
                    array[1] = byteArrayFromByteArray[0];
                    array[2] = byteArrayFromByteArray[3];
                    array[3] = byteArrayFromByteArray[2];
                    break;
                case DataFormat.BADC:
                    array[0] = byteArrayFromByteArray[2];
                    array[1] = byteArrayFromByteArray[3];
                    array[2] = byteArrayFromByteArray[0];
                    array[3] = byteArrayFromByteArray[1];
                    break;
                case DataFormat.DCBA:
                    array = byteArrayFromByteArray;
                    break;
            }

            return array;
        }

        //
        // 摘要:
        //     从字节数组中截取8个字节,并按指定字节序返回
        //
        // 参数:
        //   value:
        //     字节数组
        //
        //   start:
        //     开始索引
        //
        //   dataFormat:
        //     字节顺序，默认为ABCD
        //
        // 返回结果:
        //     字节数组
        [Description("从字节数组中截取8个字节,并按指定字节序返回")]
        public static byte[] Get8BytesFromByteArray(byte[] value, int start, DataFormat dataFormat = DataFormat.ABCD)
        {
            byte[] array = new byte[8];
            byte[] byteArrayFromByteArray = GetByteArrayFromByteArray(value, start, 8);
            if (byteArrayFromByteArray == null)
            {
                return null;
            }

            switch (dataFormat)
            {
                case DataFormat.ABCD:
                    array[0] = byteArrayFromByteArray[7];
                    array[1] = byteArrayFromByteArray[6];
                    array[2] = byteArrayFromByteArray[5];
                    array[3] = byteArrayFromByteArray[4];
                    array[4] = byteArrayFromByteArray[3];
                    array[5] = byteArrayFromByteArray[2];
                    array[6] = byteArrayFromByteArray[1];
                    array[7] = byteArrayFromByteArray[0];
                    break;
                case DataFormat.CDAB:
                    array[0] = byteArrayFromByteArray[1];
                    array[1] = byteArrayFromByteArray[0];
                    array[2] = byteArrayFromByteArray[3];
                    array[3] = byteArrayFromByteArray[2];
                    array[4] = byteArrayFromByteArray[5];
                    array[5] = byteArrayFromByteArray[4];
                    array[6] = byteArrayFromByteArray[7];
                    array[7] = byteArrayFromByteArray[6];
                    break;
                case DataFormat.BADC:
                    array[0] = byteArrayFromByteArray[6];
                    array[1] = byteArrayFromByteArray[7];
                    array[2] = byteArrayFromByteArray[4];
                    array[3] = byteArrayFromByteArray[5];
                    array[4] = byteArrayFromByteArray[2];
                    array[5] = byteArrayFromByteArray[3];
                    array[6] = byteArrayFromByteArray[0];
                    array[7] = byteArrayFromByteArray[1];
                    break;
                case DataFormat.DCBA:
                    array = byteArrayFromByteArray;
                    break;
            }

            return array;
        }

    }
}
